package com.xxdemo.site.webapi;

import com.xxdemo.site.ExternalWebServerRegistryService;
import com.xxdemo.site.validation.Hostname;
import com.xxdemo.site.WebServerDetail;
import com.xxdemo.site.WebServerDetailDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("sites")
public class ExternalWebServerRegistryController {
    private final ExternalWebServerRegistryService _serverRegistryService;

    public ExternalWebServerRegistryController(
            ExternalWebServerRegistryService webServerRegistryService) {
        this._serverRegistryService = webServerRegistryService;
    }

    @GetMapping
    public SuccessfulResult<List<WebServerDetailDto>> index() {
        /// FIXME: 此处我尚未实现业务逻辑, 查询全部第三方服务器列表
        return ArrayList::new;
    }

    @GetMapping("/{hostname}/detail")
    public HostnameQueryResult getWebServerDetailByHostnameStr(@PathVariable(name = "hostname") String hostnameStr) {
        Hostname hostname = Hostname.fromStr(hostnameStr);
        Optional<WebServerDetail> output = _serverRegistryService.queryByHostname(hostname, false);
        return output.map((WebServerDetail webServerDetail) -> (HostnameQueryResult.fromWebServerDetail(webServerDetail)))
                .orElseThrow(() -> new ErrorCanNotFindServerByHostname(hostname));
    }

    public static class ErrorCanNotFindServerByHostname extends AppBusinessLayerException {
        public ErrorCanNotFindServerByHostname(Hostname hostname) {
            super("Can not find hostname: " + hostname.getValue());
        }
    }

    /// 按主机名Hostname查询, 结果为单条服务器详情数据包WebServerDetailDto
    public static class HostnameQueryResult implements SuccessfulResult<WebServerDetailDto> {

        private final WebServerDetailDto data;

        /// 状态码始终等于200表示成功
        @SuppressWarnings("FieldCanBeLocal")
        private final Integer status = 200;

        protected HostnameQueryResult(WebServerDetailDto data) {
            this.data = data;
        }

        public Integer getStatus() {
            return status;
        }

        @Override
        public WebServerDetailDto getData() {
            return data;
        }

        /// 对默认构造函数进行封装
        public static HostnameQueryResult fromDto(WebServerDetailDto dto) {
            return new HostnameQueryResult(dto);
        }

        /// 对默认构造函数进行封装
        public static HostnameQueryResult fromWebServerDetail(WebServerDetail server) {
            WebServerDetailDto dto = new WebServerDetailDto();
            dto.setId(server.getId());
            dto.setHostname(server.getHostname());
            dto.setPublicUri(server.getPublicUri());
            dto.setServiceType(server.getServiceType());
            dto.setBriefDescription(server.getBriefDescription());
            dto.setOnlineSince(server.getOnlineSince());
            dto.setNotice(server.getNotice());
            dto.setDeprecated(server.getDeprecated());
            return new HostnameQueryResult(dto);
        }
    }
}
